function person(a, b, c) {
    return {
        name: this.name,
        a: a, b: b, c: c
    }
}

var egg = {name: 'jueyi'};


Function.prototype.newBind = function (obj) {
    /*按照MDN官方的建议，检测一下数据类型*/
    if (typeof this !== 'function') {
        throw new TypeError('错误');
    }

    var that = this;
    var arr = Array.prototype.slice.call(arguments, 1);
    /*原型跳板，空函数*/
    var o = function () {
    }

    //将返回函数设置为具名函数，有了名字的函数，才能进行关系的确认
    var newf = function () {

        var arr2 = Array.prototype.slice.call(arguments);
        //concat前后的数组顺序不能出错，否则结果顺序就不是bind的顺序了
        var arrSum = arr.concat(arr2);

        if (this instanceof o) {
            //apply会自动解决传入对象egg为null的问题
            return that.apply(this, arrSum);
        } else {
            return that.apply(obj, arrSum);
        }
    };

    /*将空函数的原型对象修改为this的原型对象，也就是说把o的原型对象修改为函数person的原型对象*/
    o.prototype = that.prototype;
    /*将newf的原型对象作为空函数的实例进行串联，也就是说把函数bibi的原型对象作为空函数的实例进行串联*/
    newf.prototype = new o;
    return newf;

};


var bibi = person.newBind(egg, '点赞', '投币');
var a = person.newBind(egg, '点赞', '投币')('充电');
var b = person.newBind(null, '点赞', '投币', '充电')();
var c = new bibi('充电');
console.log(a, b, c);


/*
var bibi = person.bind(egg, '点赞', '投币');
// bind可以使用new方法，只是this会失效 。同时，bind有柯里化的性质
var b = new bibi('充电');
console.log(b)
*/


